Sprzątanie ostrzeżeń z pytest (Py3.13 / Django 5.2 LTS)#152
Merged
Conversation
Zamiana datetime.now() → timezone.now() w miejscach, gdzie wartość trafiała do pola DateTimeField (zapis lub filtr). Przy USE_TZ=True Django emitowało RuntimeWarning "received a naive datetime" i interpretowało wartość w lokalnej strefie czasowej, co przy DST mogło powodować niespójności dat w bazie. - bpp.util.remove_old_objects (uzywane przez oswiadczenia, integrator2) - bpp.admin.templates.TemplateAdmin.template_updated filtr - ewaluacja_optymalizacja.tasks.optimization OptimizationRun .finished_at (3 miejsca) - ewaluacja_optymalizacja management commands solve_uczelnia, solve_evaluation Testowe literaly "2023-01-01 00:00:00" w pbn_export_queue zamienione na timezone.make_aware(datetime(...)). test_OstatnioZmieniony: datetime.now() -> timezone.now(). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pytest ostrzegał PytestRemovedIn9Warning "Marks applied to fixtures have no effect" (49 wystąpień w logach). Markery na fixturach i tak nie mają efektu — dostęp do bazy dziedziczy się z testu wywołującego, który ma własny @pytest.mark.django_db. W pytest 9 bedzie to blad. Dotyczy 7 fixtur w: - src/conftest.py - src/import_polon/tests/conftest.py - src/bpp/tests/test_models/test_sloty/conftest.py Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Zgodnie z konwencja projektu (CLAUDE.md: "NEVER create unittest.TestCase tests") — zamiana TestCase na zwykla funkcje pytest. Usuniecie return True eliminuje DeprecationWarning "It is deprecated to return a value that is not None from a test case". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
openpyxl deprecated StyleProxy.copy() method — used Font() konstruktor z przepisanymi atrybutami zachowujacymi istniejace wartosci name/size i doklada bold=True. Eliminuje DeprecationWarning "Call to deprecated function copy" w pbn_wysylka_oswiadczen xlsx export. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…etter Wydawnictwo_Zwarte.wydawnictwo to property z deprekacja, ktore emituje DeprecationWarning "W przyszlosci uzyj wydawca_opis" przy zapisie. Zamiana w 2 testach (test_cache.py, test_history.py) na bezposrednie ustawianie wydawca_opis. Przy okazji ruff isort uporzadkowal importy w test_history.py. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Definiowanie `class TestReport(Report)` w ciele fixture'a powodowało ponowną rejestrację modelu `long_running.testreport` przy każdym uruchomieniu testu korzystającego z fixture'a `report`, co Django sygnalizowało `RuntimeWarning: Model 'long_running.testreport' was already registered. Reloading models is not advised...`. TestReport ma teraz stałą definicję w `test_bpp.models` wraz z migracją `0003_testreport`, a fixture sprowadza się do prostego `baker.make(TestReport)`. Nieużywany nigdzie override `send_notification` (dziedziczony NullNotificationMixin i tak jest no-opem) został usunięty.
django-tables2 emits `UserWarning: Table data is of type <X> but <Y> is specified in Table.Meta.model` when the declared Meta.model does not match the row type of the queryset backing the table. `Meta.model` is only used for field introspection, so the mismatch was cosmetic — fix it by pointing it at the actual row type: - RankingAutorowTable: Autor -> Sumy (queryset is Sumy.objects...) - RaportSlotowUczelniaTable: Cache_Punktacja_Autora_Query -> RaportSlotowUczelniaWiersz (list view iterates over raportslotowuczelniawiersz_set) Drop now-unused `Autor` / `Cache_Punktacja_Autora_Query` imports.
Django emits `UnorderedObjectListWarning` and may serve duplicate or missing rows across pages when a Paginator is handed an unordered queryset. Fix the callers surfaced by the current test run: Autocomplete (bpp.views.autocomplete): - Dyscyplina_NaukowaAutocomplete — order by (kod, nazwa) - Wydawnictwo_NadrzedneAutocomplete + admin variants — order by (tytul_oryginalny, pk) - PublicZrodloAutocomplete / ZrodloAutocomplete — order by (nazwa, pk); apply to both the base queryset and the QuerySetSequence combining PBN-priority branches Paginated list views: - pbn_wysylka_oswiadczen.PublicationListView — order the combined QuerySetSequence by (-rok, tytul_oryginalny, pk) - RaportSlotowUczelnia.get_details_set — order raportslotowuczelnia wiersz_set by (autor__nazwisko, autor__imiona, pk) Model Meta: - RozbieznosciView — restore `ordering = ["id"]` that the abstract base had but the concrete Meta was silently overriding. New migration 0021 is pure AlterModelOptions (managed=False, no DDL). Pre-existing ruff findings in raport_slotow/models/uczelnia.py (C901, unused loop variable) silenced without refactoring — scope is the pagination fix, not `create_report` internals.
Dotychczas funkcja blokowała workera 10× `time.sleep(1)` czekając, aż obiekt utworzony w innej transakcji pojawi się w bazie. Teraz w razie `DoesNotExist` woła `current_task.retry(countdown=1, max_retries=no_tries)` — celery ponownie uruchomi to samo zadanie za sekundę, a worker w tym czasie obsługuje inne zadania. Po wyczerpaniu prób celery podnosi oryginalny `DoesNotExist` (kontrakt `Task.retry(exc=...)`). Usunięto `DeprecationWarning` emitowany przy każdym wywołaniu. Kontrakt: funkcję wywołujemy wyłącznie z kontekstu zadania celery (`.delay(...)`, `.apply_async(...)`, `.apply(...)`). Wywołanie funkcji-zadania wprost nie ustawia `current_task` i omija retry. Testy `analyze_file` i `task_sprobuj_wyslac_do_pbn` przerobione z bezpośredniego wywołania na wywołanie przez celery. Tam gdzie test mockuje `task.apply_async` (do weryfikacji re-schedulowania w gałęziach RETRY_*) używam `task.apply(args=(...)).get()` zamiast `.delay(...).get()` — `.delay()` trafiłoby w mock apply_async i body zadania nigdy by się nie uruchomiło. Dodano trzy testy pokrywające kontrakt `wait_for_object` w `src/long_running/tests/test_util.py` (happy path, exhaust, succeed-on-retry). Używają `.apply(throw=False)` + fixture, która tymczasowo ustawia `app.conf.task_eager_propagates=False`, bo CELERY_EAGER_PROPAGATES_EXCEPTIONS=True w bpp sprawia, że `Retry` propaguje się poza `apply()` natychmiast i rekurencyjne `retval.sig.apply(retries=retries+1)` w `Task.apply` gubi `throw=False` (używa defaultu z app.conf). Produkcyjny worker tej fixture nie wymaga.
…ync warnings
Od django-constance 4.x Config.__getattr__ wykrywa aktywną pętlę
asyncio i zwraca AsyncValueProxy zamiast wartości. Django test client
w nowszych wersjach startuje pętlę wewnętrznie, więc stringifikacja
takiego proxy w szablonie (np. {{ WYDRUK_MARGINES_GORA|default:"2cm"
}} w bare.html) emitowała:
RuntimeWarning: Synchronous access to Constance setting
'WYDRUK_MARGINES_*' inside an async loop. Use
'await config.WYDRUK_MARGINES_*' instead.
constance.utils.get_values_for_keys(keys) idzie prosto do backendu
(config._backend.mget) pomijając __getattr__ — bez detekcji pętli,
bez proxy, bez warningu. Działa identycznie w trybie sync i async.
Dotyczyło 4 testów:
- ewaluacja_optymalizacja/tests/test_discipline_pins.py
::test_reset_discipline_pins_no_unpinned_shows_warning
- import_dyscyplin/tests/test_views.py
::test_CreateImport_DyscyplinView_bledny_plik
::test_CreateImport_DyscyplinView_dobry_plik
::test_UsunImport_Dyscyplin
Produkcja — `search_publications`, `get_institution_publication_v2`,
`get_institution_statements_of_single_publication` — uderza w
paginowane endpointy PBN i używa `post_pages`/`get_pages`, czyli
oczekuje odpowiedzi o strukturze `{content, pageable, number,
totalElements, totalPages, ...}`. Te funkcje są POPRAWNE.
Mocki w testach zwracały płaską listę (albo `[]`), co w
`transport._pages` odpalało RuntimeWarning:
PBNClient.{get,post}_page request for ... did not return a paged
resource, maybe use PBNClient.{get,post} (without 'page') instead
Warning dotyczył 4 plików testowych (test_client_sync,
test_client_helpers, test_bpp_admin_helpers, test_views/test_api).
Owinąłem ok. 30 mocków w istniejący już helper
`fixtures.pbn_api.pbn_pageable_json(content)`. Produkcyjnego kodu
nie ruszam — był poprawny, to mocki nie odwzorowywały rzeczywistego
kształtu odpowiedzi.
W poprzednim refaktorze (commit 057f291 "Duże pliki na małe") deklaracja `pytest_plugins` została USUNIĘTA z `src/fixtures/conftest.py` z notatką "moved to top-level conftest.py (per pytest requirements)" — ale nigdy nie została do top-level conftest dodana. Dodatkowo `fixtures/__init__.py` robiło `from .conftest_X import *` dla wszystkich 5 modułów, więc każdy `from fixtures import …` (np. `from fixtures.playwright_fixtures import …` w `src/conftest.py:419`) pociągał je w całości PRZED pytestem. Przy rejestracji jako pluginy pytest już widział je w sys.modules → 85 ostrzeżeń: PytestAssertRewriteWarning: Module already imported so cannot be rewritten; fixtures.conftest_{models,publications,system,browser, disciplines} Fix: - Dodaję `pytest_plugins = [...]` w top-level `src/conftest.py` (5 modułów conftest_*). Kolejność deklaracji wewnątrz modułu nie ma znaczenia — pytest czyta atrybut po pełnym załadowaniu. - `fixtures/__init__.py` NIE importuje już conftest_*, tylko `fixtures.const`, `fixtures.pbn_api`, `fixtures.wydawnictwa` — moduły, które nie są pytest plugins, więc eager import ich nie psuje. - Stałe modułowe `NORMAL_DJANGO_USER_{LOGIN,PASSWORD}` i `JEDNOSTKA_{UCZELNI,PODRZEDNA}` przeniesione z conftest_browser / conftest_models do nowego `fixtures/const.py`. conftest_X importuje je stamtąd; `fixtures/__init__.py` re-eksportuje przez `from .const import *`. Jednocześnie naprawiam regresję z commita `1a372897` (grupa [3] — UnorderedObjectListWarning): `.order_by("nazwa", "pk")` na `QuerySetSequence` w `ZrodloAutocomplete.get_queryset()` propagowało się do sliced sub-queryset (`qs.filter(...)[:10]`), co od Django 4.x zgłasza `TypeError: Cannot reorder a query once a slice has been taken`. Bazowy queryset `_get_base_queryset` już ma .order_by, więc każdy slice ma porządek — wystarcza; kolejność między gałęziami PBN jest priorytetowa (intencjonalnie, nie alfabetyczna).
…r pyoai/webtest MOAI-iplweb 2.0.1 (upstream fork by same author) naprawia datetime.utcnow() -> datetime.now(UTC). Zniknął warning z moai/oai.py. Downgrade tranzytywny sqlalchemy 2.x -> 1.4 i setuptools 80 -> 79 wymuszony przez moai-iplweb 2.0.1 constraints (sqlalchemy<2, setuptools<80). Dla dwóch pozostałych zewnętrznych warningów bez lokalnego forka (grupy [10] i [11] TODO) dodałem targetowane filtry w pytest.ini: pyoai 2.5.0 (oaipmh.server) - datetime.utcnow, webtest 3.0.7 (webtest.forms) - bs4.findAll. Zgłoszenia upstream w toku.
Release 1.10.2 w forku user-a dodaje `get_joining_fields()` do inline'owej klasy `JoinField` w `TriggerFilterQuery.__init__` (`denorm/denorms.py:361`). Dzięki temu Django 6.0 przestaje emitować: RemovedInDjango60Warning: The usage of get_joining_columns() in Join is deprecated. Implement get_joining_fields() instead. Zweryfikowane przez uruchomienie `src/bpp/tests/test_views/test_oai.py` z `-W "error:The usage of get_joining_columns:DeprecationWarning"` — 6 passed, 0 warningów.
4b6af41 to
1fff2f0
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Zbiorczy porządek 17 grup ostrzeżeń, które pokazywały się w pełnym runie pytest (log
/tmp/bpp-after-fixes.log, Py 3.13 + Django 5.2). Po tych 16 commitach wszystkie kategorie są zamknięte — albo naprawione w kodzie / zależnościach, albo zgłoszone upstream z targetowanym filtrem wpytest.ini.Zrobione w tym PR
Grupy wg oryginalnego numerowania z audytu:
timezone.now()w produkcji (bpp/util.py,bpp/admin/templates.py,ewaluacja_optymalizacja/tasks, ...).1df67bddget_values_for_keysw context processor zamiastgetattr(config, X).eb9f30d5UnorderedObjectListWarning→ stabilneorder_byw autocomplete,pbn_wysylka_oswiadczen,RaportSlotowUczelnia,RozbieznosciView.1a372897PBNClient.get_page"did not return a paged resource" — fix w mockach testowych (wrap wpbn_pageable_json), kod produkcyjny bez zmian.be63367dPytestAssertRewriteWarning— przywróconypytest_pluginsw top-levelconftest.py+fixtures.constzamiast eagerfrom .conftest_X import *.ce9b9588@pytest.mark.*nałożone na fixture → usunięte.0f624d26Meta.modelmismatch w tabelach django-tables2 → wyrównane.d9aed17bopenpyxl cell.font.copy()→Font(...).ad33697fwydawnictwo=setter →wydawca_opis=w testach.73f0bce9itertools.countwCounterMixin(django-flexible-reports) → bump 0.2.12 + release na PyPI, bump zależności.b58c4bc6create_test_db/tests.py— pytest-style.9efa97c9wait_for_object→ celery retry zamiasttime.sleep(10).d0948c6fTestReportrejestrowany 2× → przeniesiony dotest_bppapp z migracją.89436d43utcnowifindAll— bump MOAI-iplweb 2.0.1 (fix upstream), filter wpytest.inidla pyoai i webtest. Dodatkowo otwarty PR upstreaminfrae/pyoai#61.8b0737b8get_joining_columnsdeprecation → fix upstream wdjango-denorm-iplweb1.10.2 + release na PyPI + bump zależności.4b6af418Tylko grupa [7] (
FORMS_URLFIELD_ASSUME_HTTPS) była na gałęzifeature/django-5.2— zamknięta wcześniej tam (4d44441e), nie ma jej w tym PR.Test plan
uv run pytest src/long_running/ src/integrator2/tests/test_tasks.py src/pbn_export_queue/tests/test_tasks.py— 54 passed, 0 warningówTa funkcja niepotrzebnie.uv run pytest src/pbn_api/tests/test_client_sync.py src/pbn_api/tests/test_client_helpers.py src/pbn_api/tests/test_bpp_admin_helpers.py src/bpp/tests/test_views/test_api.py -W "error:did not return a paged resource:RuntimeWarning"— 44 passed.uv run pytest src/ewaluacja_optymalizacja/tests/test_discipline_pins.py::test_reset_discipline_pins_no_unpinned_shows_warning src/import_dyscyplin/tests/test_views.py::{test_CreateImport_DyscyplinView_bledny_plik,test_CreateImport_DyscyplinView_dobry_plik,test_UsunImport_Dyscyplin} -W "error:Synchronous access to Constance:RuntimeWarning"— 4 passed.uv run pytest src/raport_slotow/tests/test_views/test_raport_slotow_uczelnia.py src/raport_slotow/tests/test_views/test_uczelnia.py src/ranking_autorow/tests.py -W "error:Table data is of type:UserWarning"— 31 passed.uv run pytest src/bpp/tests/test_autocomplete/test_autocomplete_security.py ... -W "error::django.core.paginator.UnorderedObjectListWarning"— 106 passed.uv run pytest src/bpp/tests/test_views/test_oai.py -W "error:The usage of get_joining_columns:DeprecationWarning"— 6 passed.Dependencies bumped
django-flexible-reports0.2.11 → 0.2.12 (PyPI, własny fork)MOAI-iplweb==2.0.0 → >=2.0.1 (PyPI, własny fork — wymusił downgradesqlalchemy2.x → 1.4 isetuptools80 → 79 przez transitive constraints)django-denorm-iplweb>=1.10.1 → >=1.10.2 (PyPI, własny fork)Upstream kontrybucje
infrae/pyoai#61— fixdatetime.utcnow(); do czasu mergea filter wpytest.ini.🤖 Generated with Claude Code